<template>
  <div>
    <van-nav-bar fixed>
      <template #left>
        <img class="logo" src="@/assets/logo.png" alt="" />
      </template>
      <template #right>
        <van-icon name="search" size="18" color="white" @click="moveSearchPageFn"/>
      </template>
    </van-nav-bar>

    <!--
    细节：
    van-tab导航栏通过for循环出来的，与之一一对应的是内容列表不是上来就创建的，默认创建当前激活的导航对应的内容列表组件，
    第一次切换到对应频道时，才会创建下属的articleList组件 ->created方法
    第二次切换就是显示/隐藏
    解决：在每个articleList组件中created请求数据，第一次切换频道时是创建下属的内容列表组件，会调用created，第二次切换显示隐藏。数据就不会由变化
    向articleList组件传入请求文章列表需要的id（导航栏数据id）
   -->
    <div class="main">
      <van-tabs
        v-model="channelId"
        sticky
        offset-top="2.9rem"
        color="#007bff"
        animated
        @change="channelChangeFn"
      >
        <van-tab
          :title="obj.name"
          v-for="obj in userChannelsList"
          :key="obj.id"
          :name="obj.id"
        >
          <ArticleList :channelId="channelId"></ArticleList>
        </van-tab>
      </van-tabs>
      <!-- 编辑频道图标 -->
      <van-icon
        name="plus"
        size="0.37333334rem"
        class="moreChannels"
        @click="channelPopupFn"
      />
    </div>
    <!-- 编辑频道弹出层 -->
    <van-popup class="channelEdit" v-model="show" get-container="body">
      <ChannelEdit
        :userList="userChannelsList"
        :unCheckList="unCheckChannelList"
        @addChannelEV="addChannelFn"
        @removeChannelEV="removeChannelFn"
        @closeEV="closeFn"
        ref="editRef"
        v-model="channelId"
      ></ChannelEdit>
    </van-popup>
  </div>
</template>

<script>
import ArticleList from './components/ArticleList.vue'
import { getAllChannelsAPI, getUserChannelsAPI, updateChannelsListAPI, removeChannelsAPI } from '@/api'
import ChannelEdit from './channelEdit.vue'
import { nextTick } from 'vue'
// 目标：获取不同的文章列表 需传递不同频道id
// 想法： 让van-tabs的v-model关联频道id
export default {
  data () {
    return {
      channelId: 0,
      userChannelsList: [], // 用于存放请求来的频道列表
      allChannelsList: [], // 所有频道列表
      articleList: [], // 文章列表
      show: false, // 弹出层显示状态
      channelScrollTObj: {} // 通过id来存放对应频道的scrolltop {推荐频道id : 滚动条高度, html频道id : 滚动条高度}
    }
  },
  components: {
    ArticleList,
    ChannelEdit
  },
  async created () {
    // 频道列表
    const res = await getUserChannelsAPI()
    console.log('频道', res)
    this.userChannelsList = res.data.data.channels
    // 所有频道列表
    const res2 = await getAllChannelsAPI()
    console.log('所有频道', res2)
    this.allChannelsList = res2.data.data.channels
    // 文章列表
    // this.channelChangeFn()
  },
  methods: {
    // tabs切换事件 ->获取文章列表数据
    channelChangeFn () {
    // const res2 = await getArticlesAPI({
    //   channel_id: this.channelId, // 先默认请求推荐频道数据
    //   timestamp: (new Date()).getTime()
    // })
    // console.log(res2)
    // this.articleList = res2.data.data.results
      console.log(22)
      // nextTick : 在下一次DOM更新结束后调用
      nextTick(() => {
        document.documentElement.scrollTop = this.channelScrollTObj[this.channelId]
      })
    },
    // + 号 点击事件
    channelPopupFn () {
      this.show = true
    },
    // 添加频道
    async addChannelFn (channelObj) {
      this.userChannelsList.push(channelObj)
      // 问题：为何只需要push，不需要从下边列表移除？
      // 因为computed 计算属性是响应式的，数组发生变化就也会更新

      // 把最新的数组发送给后台
      // 数组中对象字段 -> 转换
      // 推荐频道不能传递 - filter筛选出推荐频道剩下的频道
      // const newArr = this.userChannelsList.filter(obj => obj.id !== 0)
      // newArr.forEach((obj,index) => {
      //   delete obj.name
      //   obj.seq = index
      // })
      // const res = await updateChannelsListAPI({
      //  channels: this.userChannelsList //传入的是对象
      // })
      // 以上代码出了问题 新增时名字被删除了，
      // 原因: 所有数组里的对象，都是同一个内存地址，删除name键值对， channelEdit.vue中的对象name键值对也没了
      // 解决方法：不能操作原数组，
      const newArr = this.userChannelsList.filter(obj => obj.id !== 0)
      const theNewArr = newArr.map((obj, index) => {
        const newObj = { ...obj } // 拷贝（浅拷贝）
        // delete   对象.属性名 删除键值对
        delete newObj.name // 删除obj中的name键值对
        newObj.seq = index // 添加一个seq 键值对
        return newObj // 让map方法把新对象收集起来形成一个新的数组
      })
      const res = await updateChannelsListAPI({
        channels: theNewArr
      })
      console.log(res)
    },
    // 删除频道
    async removeChannelFn (channelObj) {
      // 把接收的对象从数组中删除 先把它从数组中找出来
      const index = this.userChannelsList.findIndex(obj => obj.id === channelObj.id)
      this.userChannelsList.splice(index, 1)
      // 把删除后的数组传给后台
      // 第一种方式：把删除后的用户数组的数据，再覆盖时的发给后台
      // 需要把上面的更新数组过程，封装成一个函数，add和remove里调用(笔记里)
      // 第二种:调用删除的接口
      const res = await removeChannelsAPI({
        channelId: channelObj.id
      })
      console.log(res)
      // 删除接口响应码204 (not content) 没有返回内容
    },
    // 关闭弹出层
    closeFn () {
      this.show = false
      // 关闭弹出层时，如果处于编辑状态，关闭编辑状态
      // 通过 ref 获取 子组件修改
      this.$refs.editRef.isEdit = false
    },
    // 路由跳转 -> 搜索页面
    moveSearchPageFn () {
      this.$router.push('/search')
    },
    // 监听网页滚动事件
    scrollFn () {
      this.$route.meta.scrollT = document.documentElement.scrollTop
      console.log(1111)
      // 同时保存当前频道的滚动条高度
      this.channelScrollTObj[this.channelId] = document.documentElement.scrollTop
      console.log(this.channelScrollTObj)
    }
  },
  computed: {
    // 把两个数组中重复的对象拿出来，返回新数组
    unCheckChannelList () {
      const newArr = this.allChannelsList.filter((bigObj) => {
        const index = this.userChannelsList.findIndex((smallObj) => {
          return smallObj.id === bigObj.id
        })
        // 如果findIndex找到-1
        if (index > -1) {
          return false
        } else {
          return true
        }
      })
      return newArr
    }
  },
  // activated : 当组件被缓存(<keep-alive>)时, 激活组件时调用
  activated () {
    // console.log(this.$route)
    // 在组件被激活时,添加滚动监听事件,监听滚动条高度
    window.addEventListener('scroll', this.scrollFn)
    document.documentElement.scrollTop = this.$route.meta.scrollT
    console.log(111)
  },
  // deactivated : 当组件被缓存时(<keep-alive>),离开组件时调用
  deactivated () {
    // 离开缓存的组件时,移除监听事件
    window.removeEventListener('scroll', this.scrollFn)
  }
}
</script>

<style scoped lang="less">
.logo {
  width: 100px;
  height: 30px;
}
.main {
  padding-top: 46px;
}
// 设置 tabs 容器的样式
/deep/ .van-tabs__wrap {
  padding-right: 30px;
  background-color: #fff;
}

// 设置小图标的样式
.moreChannels {
  position: fixed;
  top: 62px;
  right: 8px;
  z-index: 999;
}
// 频道编辑样式
.channelEdit {
  width: 100vw;
  height: 100vh;
}
</style>
